////////////////////////////////////////////////////////////////////////////
//
//  CryEngine Source File.
//  Copyright (C), Crytek.
// -------------------------------------------------------------------------
//  File name:   IPlatformOS_PC.h
//  Created:     18/12/2009 by Alex Weighell.
//  Description: Interface to the Platform OS
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#ifndef __PLATFORMOS_PC_H_
#define __PLATFORMOS_PC_H_

#if !defined(XENON) && !defined(PS3) && !defined(gringo)

#include "IPlatformOS.h"
#include <CryListenerSet.h>
#include <IGameFramework.h>



namespace ZipDir
{
	class FileEntryTree;

	class CacheRW;
	TYPEDEF_AUTOPTR(CacheRW);
	typedef CacheRW_AutoPtr CacheRWPtr;
}


class CPlatformOS_PC : public IPlatformOS, public IPlatformOS::IPlatformListener, public ISystemEventListener, public IGameFrameworkListener
{
public:

	CPlatformOS_PC( const uint8 createParams );

	// ~IPlatformOS

	// Called each frame to update the platform listener
	VIRTUAL void Tick(float realFrameTime);

	// Local user profile functions to check/initiate user sign in:
	// See IPlatformOS.h for documentation.
	VIRTUAL unsigned int	UserGetMaximumSignedInUsers() const;
	VIRTUAL bool					UserIsSignedIn(unsigned int userIndex) const;
	VIRTUAL bool 					UserIsSignedIn(const IPlatformOS::TUserName& userName, unsigned int& outUserIndex) const { if(!m_bSignedIn) return false; outUserIndex = 0; return true; }
	VIRTUAL bool					UserDoSignIn(unsigned int numUsersRequested, unsigned int controllerIndex);
	VIRTUAL void					UserSignOut(unsigned int user) {}
	VIRTUAL int						GetFirstSignedInUser() const;
	VIRTUAL unsigned int	UserGetPlayerIndex(const char* userName) const { return 0; }
	VIRTUAL bool					UserGetName(unsigned int userIndex, IPlatformOS::TUserName& outName) const;
	VIRTUAL bool					UserGetOnlineName(unsigned int userIndex, IPlatformOS::TUserName& outName) const;
	VIRTUAL bool					UserSelectStorageDevice(unsigned int userIndex, bool bForceUI = false) { return true; } // always hard drive
	VIRTUAL bool					GetUserProfilePreference(unsigned int user, IPlatformOS::EUserProfilePreference ePreference, SUserProfileVariant& outResult) const;
	VIRTUAL bool					MountSaveFile(unsigned int userIndex) { return true; }
	VIRTUAL IFileFinderPtr GetFileFinder(unsigned int user) { return IFileFinderPtr(new CFileFinderCryPak()); }
	VIRTUAL void					MountDLCContent(IDLCListener* pCallback, unsigned int user, const uint8 keyData[16]);

	VIRTUAL bool					CanRestartTitle() const;
	VIRTUAL void					RestartTitle(const char* pTitle);

	VIRTUAL bool UsePlatformSavingAPI() const;
	VIRTUAL bool BeginSaveLoad(unsigned int user, bool bSave);
	VIRTUAL void EndSaveLoad(unsigned int user);
	VIRTUAL IPlatformOS::ISaveReaderPtr SaveGetReader(const char* fileName, unsigned int user);
	VIRTUAL IPlatformOS::ISaveWriterPtr SaveGetWriter(const char* fileName, unsigned int user);

	VIRTUAL bool KeyboardStart(unsigned int inUserIndex, unsigned int flags, const wchar_t* title, const wchar_t* initialInput, int maxInputLength, IVirtualKeyboardEvents *pInCallback);
	VIRTUAL bool KeyboardIsRunning();
	VIRTUAL bool KeyboardCancel();

	VIRTUAL bool StringVerifyStart(const wchar_t* inString, IStringVerifyEvents *pInCallback);
	VIRTUAL bool IsVerifyingString();

	VIRTUAL void AddListener(IPlatformOS::IPlatformListener* pListener, const char* szName);
	VIRTUAL void RemoveListener(IPlatformOS::IPlatformListener* pListener);
	VIRTUAL void NotifyListeners(SPlatformEvent& event);

	VIRTUAL ILocalizationManager::EPlatformIndependentLanguageID GetSystemLanguage();
	VIRTUAL const char* GetSKUId();
	VIRTUAL ILocalizationManager::TLocalizatonBitfield GetSystemSupportedLanguages();

	VIRTUAL IPlatformOS::EMsgBoxResult DebugMessageBox(const char* body, const char* title, unsigned int flags=0) const;

	VIRTUAL bool PostLocalizationBootChecks();
	VIRTUAL bool PostBootCheckProcessing();
	VIRTUAL bool ShowBootCheckMessage(const bool bShow);

	VIRTUAL void GetMemoryUsage(ICrySizer *pSizer) const;

	VIRTUAL bool DebugSave(SDebugDump& dump);

	VIRTUAL bool ConsoleLoadGame(IConsoleCmdArgs* pArgs);

	VIRTUAL const char* const GetHostName();

	VIRTUAL void InitEncryptionKey(const char* pMagic, size_t magicLength, const uint8* pKey, size_t keyLength);

	VIRTUAL void GetEncryptionKey(const std::vector<char>** pMagic = NULL, const std::vector<uint8>** pKey = NULL);

	VIRTUAL EUserPIIStatus GetUserPII(unsigned int inUser, SUserPII *pOutPII);
	
	VIRTUAL IPlatformOS::EZipExtractFail ExtractZips( const char* path );

	VIRTUAL void SetOpticalDriveIdle(bool bIdle);
	VIRTUAL void AllowOpticalDriveUsage(bool bAllow);
	// ~IPlatformOS

	// IPlatformOS::IPlatformListener
	VIRTUAL void OnPlatformEvent(const IPlatformOS::SPlatformEvent& _event);
	// ~IPlatformOS::IPlatformListener

	// ISystemEventListener
	VIRTUAL void OnSystemEvent( ESystemEvent event,UINT_PTR wparam,UINT_PTR lparam );
	// ~ISystemEventListener

	// IGameFrameworkListener
	VIRTUAL void OnPostUpdate(float fDeltaTime) {}
	VIRTUAL void OnSaveGame(ISaveGame* pSaveGame) {}
	VIRTUAL void OnLoadGame(ILoadGame* pLoadGame) {}
	VIRTUAL void OnLevelEnd(const char* nextLevel) {}
	VIRTUAL void OnActionEvent(const SActionEvent& event);
	// ~IGameFrameworkListener

private:

	void SaveDirtyFiles();
	IPlatformOS::EZipExtractFail RecurseZipContents( ZipDir::FileEntryTree* pSourceDir, const char* currentPath, ZipDir::CacheRWPtr pCache );
	bool DecryptAndCheckSigning(const char *pInData, int inDataLen, char **pOutData, int *pOutDataLen, const uint8 key[16]);

private:
	CStableFPSWatcher m_fpsWatcher;
	CListenerSet<IPlatformOS::IPlatformListener*> m_listeners;
	std::vector<char> m_encryptionMagic;
	std::vector<uint8> m_encryptionKey;
	float m_delayLevelStartIcon;
	bool m_bSignedIn;
	bool m_bSaving;
	bool m_bAllowMessageBox;
	bool m_bLevelLoad;
	bool m_bSaveDuringLevelLoad;
};

#endif
#endif
